{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 特征工程\n",
    "\n",
    "用于对原始数据做必要的数据预处理和特征编码，使得变换后的特征符合模型要求"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1、导入必要的工具包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2、读取数据\n",
    "\n",
    "对于简单的数据集可以直接送入回归模型；通常我们需要先对原数据进行必要的特征编码和处理（特征工程），编码后再送入模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CRIM</th>\n",
       "      <th>ZN</th>\n",
       "      <th>INDUS</th>\n",
       "      <th>CHAS</th>\n",
       "      <th>NOX</th>\n",
       "      <th>RM</th>\n",
       "      <th>AGE</th>\n",
       "      <th>DIS</th>\n",
       "      <th>RAD</th>\n",
       "      <th>TAX</th>\n",
       "      <th>PTRATIO</th>\n",
       "      <th>B</th>\n",
       "      <th>LSTAT</th>\n",
       "      <th>MEDV</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.00632</td>\n",
       "      <td>18</td>\n",
       "      <td>2.31</td>\n",
       "      <td>0</td>\n",
       "      <td>0.538</td>\n",
       "      <td>6.575</td>\n",
       "      <td>65.2</td>\n",
       "      <td>4.0900</td>\n",
       "      <td>1</td>\n",
       "      <td>296</td>\n",
       "      <td>15</td>\n",
       "      <td>396.90</td>\n",
       "      <td>4.98</td>\n",
       "      <td>24.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.02731</td>\n",
       "      <td>0</td>\n",
       "      <td>7.07</td>\n",
       "      <td>0</td>\n",
       "      <td>0.469</td>\n",
       "      <td>6.421</td>\n",
       "      <td>78.9</td>\n",
       "      <td>4.9671</td>\n",
       "      <td>2</td>\n",
       "      <td>242</td>\n",
       "      <td>17</td>\n",
       "      <td>396.90</td>\n",
       "      <td>9.14</td>\n",
       "      <td>21.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.02729</td>\n",
       "      <td>0</td>\n",
       "      <td>7.07</td>\n",
       "      <td>0</td>\n",
       "      <td>0.469</td>\n",
       "      <td>7.185</td>\n",
       "      <td>61.1</td>\n",
       "      <td>4.9671</td>\n",
       "      <td>2</td>\n",
       "      <td>242</td>\n",
       "      <td>17</td>\n",
       "      <td>392.83</td>\n",
       "      <td>4.03</td>\n",
       "      <td>34.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.03237</td>\n",
       "      <td>0</td>\n",
       "      <td>2.18</td>\n",
       "      <td>0</td>\n",
       "      <td>0.458</td>\n",
       "      <td>6.998</td>\n",
       "      <td>45.8</td>\n",
       "      <td>6.0622</td>\n",
       "      <td>3</td>\n",
       "      <td>222</td>\n",
       "      <td>18</td>\n",
       "      <td>394.63</td>\n",
       "      <td>2.94</td>\n",
       "      <td>33.4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.06905</td>\n",
       "      <td>0</td>\n",
       "      <td>2.18</td>\n",
       "      <td>0</td>\n",
       "      <td>0.458</td>\n",
       "      <td>7.147</td>\n",
       "      <td>54.2</td>\n",
       "      <td>6.0622</td>\n",
       "      <td>3</td>\n",
       "      <td>222</td>\n",
       "      <td>18</td>\n",
       "      <td>396.90</td>\n",
       "      <td>5.33</td>\n",
       "      <td>36.2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      CRIM  ZN  INDUS  CHAS    NOX     RM   AGE     DIS  RAD  TAX  PTRATIO  \\\n",
       "0  0.00632  18   2.31     0  0.538  6.575  65.2  4.0900    1  296       15   \n",
       "1  0.02731   0   7.07     0  0.469  6.421  78.9  4.9671    2  242       17   \n",
       "2  0.02729   0   7.07     0  0.469  7.185  61.1  4.9671    2  242       17   \n",
       "3  0.03237   0   2.18     0  0.458  6.998  45.8  6.0622    3  222       18   \n",
       "4  0.06905   0   2.18     0  0.458  7.147  54.2  6.0622    3  222       18   \n",
       "\n",
       "        B  LSTAT  MEDV  \n",
       "0  396.90   4.98  24.0  \n",
       "1  396.90   9.14  21.6  \n",
       "2  392.83   4.03  34.7  \n",
       "3  394.63   2.94  33.4  \n",
       "4  396.90   5.33  36.2  "
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(r'boston_housing.csv')\n",
    "#观察前五行，了解数据每列（特征）的概况\n",
    "df.head()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3、特征工程 \n",
    "\n",
    "### 3.1 数据去噪 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(506, 14)\n",
      "(490, 14)\n"
     ]
    }
   ],
   "source": [
    "#删除大于等于50的赝本\n",
    "print(df.shape)\n",
    "df = df[df.MEDV < 50]\n",
    "#输出样本数和特征维数\n",
    "print(df.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.2 数据分离\n",
    "\n",
    "从原始数据中分离输入特征x和标签y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "y=df['MEDV']\n",
    "X=df.drop('MEDV',axis=1)\n",
    "'''\n",
    "DataFrame.drop(labels=None,axis=0, index=None, columns=None, inplace=False)\n",
    "labels 就是要删除的行列的名字，用列表给定\n",
    "axis 默认为0，指删除行，因此删除columns时要指定axis=1；\n",
    "index 直接指定要删除的行\n",
    "columns 直接指定要删除的列\n",
    "inplace=False，默认该删除操作不改变原数据，而是返回一个执行删除操作后的新dataframe；\n",
    "inplace=True，则会直接在原数据上进行删除操作，删除后无法返回。\n",
    "'''\n",
    "\n",
    "log_y = np.log1p(y)  #尝试对y（房屋价格）做log变换 log1p = log（y+1）\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.3 离散性特征编码\n",
    "\n",
    "离散特征可以通过独热编码（one-hot encode），将原来有K种取值的离散型特征变成K维0-1编码特征，这K维特征中只有一个是1（独热），其余维度均为0。独热编码可以使用**pandas**的**get_dummies**方法（哑编码）或者**scikit-Learn**中的**OneHotEncoder**类来实现。\n",
    "\n",
    "> 离散特征的编码分为两种情况：\n",
    "1、离散特征的取值之间没有大小的意义，比如color：[red,blue],那么就使用one-hot编码\n",
    "2、离散特征的取值有大小的意义，比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}\n",
    "\n",
    "> 可以这样理解，对于每一个特征，如果它有m个可能值，那么经过独热编码后，就变成了m个二元特征（如成绩这个特征有好，中，差变成one-hot就是100, 010, 001）。并且，这些特征互斥，每次只有一个激活。因此，数据会变成稀疏的。\n",
    "这样做的好处主要有：\n",
    "解决了分类器不好处理属性数据的问题\n",
    "在一定程度上也起到了扩充特征的作用\n",
    "\n",
    "\n",
    "**get_dummies**方法要求输入特征的类型是非数值型；而**OneHotEncoder**要求输入的是整数(object)，如果是字符串要先使用*LabelEncoder*变成整数（注意：LabelEncoder输出的是一维数组，而OneHotEncoder要求输出的是二维数组，需要在二者之间进行数值转化）\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Rad的含义是距离高速公路的便利指数，数值型的，可换成离散特征/类别型特征编码\n",
    "X[\"RAD\"].astype(\"object\")\n",
    "x_cat = X[\"RAD\"]\n",
    "x_cat = pd.get_dummies(x_cat,prefix = 'RAD')\n",
    "\n",
    "X=X.drop(\"RAD\",axis = 1)\n",
    "\n",
    "#特征名称，用于保存特征工程结果\n",
    "feat_names = X.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>RAD_1</th>\n",
       "      <th>RAD_2</th>\n",
       "      <th>RAD_3</th>\n",
       "      <th>RAD_4</th>\n",
       "      <th>RAD_5</th>\n",
       "      <th>RAD_6</th>\n",
       "      <th>RAD_7</th>\n",
       "      <th>RAD_8</th>\n",
       "      <th>RAD_24</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   RAD_1  RAD_2  RAD_3  RAD_4  RAD_5  RAD_6  RAD_7  RAD_8  RAD_24\n",
       "0      1      0      0      0      0      0      0      0       0\n",
       "1      0      1      0      0      0      0      0      0       0\n",
       "2      0      1      0      0      0      0      0      0       0\n",
       "3      0      0      1      0      0      0      0      0       0\n",
       "4      0      0      1      0      0      0      0      0       0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_cat.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.4 数值型特征预处理\n",
    "\n",
    "Scikit_Learn提供的数据预处理功能：http://scikit-learn.org/stable/modules/preprocessing.html\n",
    "\n",
    "对于本次的数据集特征均为数值型特征。在数据探索阶段发现各特征差异较大，所以需要对数据进行标准化预处理。标准化的目的在于避免原始特征值差异过大，导致训练的到的参数权重单位不一致，无法比较各特征的重要性。另外，一些优化算法（如随机梯度下降及其改进版本）只在各特征尺度差不多的情况下才能保证收敛。\n",
    "\n",
    "\n",
    "#### 数值特征标准化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#数据标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "#分别初始化对特征和目标值的标准化器\n",
    "ss_X=StandardScaler()\n",
    "ss_y=StandardScaler()\n",
    "\n",
    "ss_log_y = StandardScaler()\n",
    "#fit(): Method calculates the parameters μ and σ and saves them as internal objects.'\n",
    "#transform(): Method using these calculated parameters apply the transformation to a particular dataset.\n",
    "#fit_transform()：将前两种方法合并，fit + transform，然后对数据集使用。\n",
    "X= ss_X.fit_transform(X)\n",
    "\n",
    "#对y标准化是非必须的，但是好处是不同问题的w差异不大，同时正则参数的范围也有限\n",
    "y = ss_y.fit_transform(y.values.reshape(-1,1))\n",
    "log_y = ss_y.fit_transform(log_y.values.reshape(-1,1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4.保存特征工程的结果到文件，供机器学习模型使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "fe_data = pd.DataFrame(data = X,columns = feat_names,index = df.index)\n",
    "fe_data = pd.concat([fe_data,x_cat],axis=1,ignore_index = False)\n",
    "\n",
    "#加上标签\n",
    "fe_data[\"MEDV\"] = y\n",
    "fe_data[\"log_MEDV\"]= log_y\n",
    "\n",
    "#保存结果到文件\n",
    "fe_data.to_csv('FE_boston_housing.csv',index =False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>CRIM</th>\n",
       "      <th>ZN</th>\n",
       "      <th>INDUS</th>\n",
       "      <th>CHAS</th>\n",
       "      <th>NOX</th>\n",
       "      <th>RM</th>\n",
       "      <th>AGE</th>\n",
       "      <th>DIS</th>\n",
       "      <th>TAX</th>\n",
       "      <th>PTRATIO</th>\n",
       "      <th>...</th>\n",
       "      <th>RAD_2</th>\n",
       "      <th>RAD_3</th>\n",
       "      <th>RAD_4</th>\n",
       "      <th>RAD_5</th>\n",
       "      <th>RAD_6</th>\n",
       "      <th>RAD_7</th>\n",
       "      <th>RAD_8</th>\n",
       "      <th>RAD_24</th>\n",
       "      <th>MEDV</th>\n",
       "      <th>log_MEDV</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.417401</td>\n",
       "      <td>0.302696</td>\n",
       "      <td>-1.291856</td>\n",
       "      <td>-0.250812</td>\n",
       "      <td>-0.139895</td>\n",
       "      <td>0.505040</td>\n",
       "      <td>-0.109432</td>\n",
       "      <td>0.121208</td>\n",
       "      <td>-0.667101</td>\n",
       "      <td>-1.415179</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.300878</td>\n",
       "      <td>0.446452</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>-0.414992</td>\n",
       "      <td>-0.486479</td>\n",
       "      <td>-0.593329</td>\n",
       "      <td>-0.250812</td>\n",
       "      <td>-0.731821</td>\n",
       "      <td>0.269017</td>\n",
       "      <td>0.377488</td>\n",
       "      <td>0.537330</td>\n",
       "      <td>-0.988734</td>\n",
       "      <td>-0.516361</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>-0.004571</td>\n",
       "      <td>0.166718</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>-0.414995</td>\n",
       "      <td>-0.486479</td>\n",
       "      <td>-0.593329</td>\n",
       "      <td>-0.250812</td>\n",
       "      <td>-0.731821</td>\n",
       "      <td>1.439934</td>\n",
       "      <td>-0.255152</td>\n",
       "      <td>0.537330</td>\n",
       "      <td>-0.988734</td>\n",
       "      <td>-0.516361</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1.662674</td>\n",
       "      <td>1.433933</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-0.414412</td>\n",
       "      <td>-0.486479</td>\n",
       "      <td>-1.310933</td>\n",
       "      <td>-0.250812</td>\n",
       "      <td>-0.826186</td>\n",
       "      <td>1.153335</td>\n",
       "      <td>-0.798939</td>\n",
       "      <td>1.056878</td>\n",
       "      <td>-1.107857</td>\n",
       "      <td>-0.066953</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1.497222</td>\n",
       "      <td>1.331120</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-0.410202</td>\n",
       "      <td>-0.486479</td>\n",
       "      <td>-1.310933</td>\n",
       "      <td>-0.250812</td>\n",
       "      <td>-0.826186</td>\n",
       "      <td>1.381694</td>\n",
       "      <td>-0.500390</td>\n",
       "      <td>1.056878</td>\n",
       "      <td>-1.107857</td>\n",
       "      <td>-0.066953</td>\n",
       "      <td>...</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1.853580</td>\n",
       "      <td>1.548010</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 23 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       CRIM        ZN     INDUS      CHAS       NOX        RM       AGE  \\\n",
       "0 -0.417401  0.302696 -1.291856 -0.250812 -0.139895  0.505040 -0.109432   \n",
       "1 -0.414992 -0.486479 -0.593329 -0.250812 -0.731821  0.269017  0.377488   \n",
       "2 -0.414995 -0.486479 -0.593329 -0.250812 -0.731821  1.439934 -0.255152   \n",
       "3 -0.414412 -0.486479 -1.310933 -0.250812 -0.826186  1.153335 -0.798939   \n",
       "4 -0.410202 -0.486479 -1.310933 -0.250812 -0.826186  1.381694 -0.500390   \n",
       "\n",
       "        DIS       TAX   PTRATIO  ...  RAD_2  RAD_3  RAD_4  RAD_5  RAD_6  \\\n",
       "0  0.121208 -0.667101 -1.415179  ...      0      0      0      0      0   \n",
       "1  0.537330 -0.988734 -0.516361  ...      1      0      0      0      0   \n",
       "2  0.537330 -0.988734 -0.516361  ...      1      0      0      0      0   \n",
       "3  1.056878 -1.107857 -0.066953  ...      0      1      0      0      0   \n",
       "4  1.056878 -1.107857 -0.066953  ...      0      1      0      0      0   \n",
       "\n",
       "   RAD_7  RAD_8  RAD_24      MEDV  log_MEDV  \n",
       "0      0      0       0  0.300878  0.446452  \n",
       "1      0      0       0 -0.004571  0.166718  \n",
       "2      0      0       0  1.662674  1.433933  \n",
       "3      0      0       0  1.497222  1.331120  \n",
       "4      0      0       0  1.853580  1.548010  \n",
       "\n",
       "[5 rows x 23 columns]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fe_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Int64Index: 490 entries, 0 to 505\n",
      "Data columns (total 23 columns):\n",
      "CRIM        490 non-null float64\n",
      "ZN          490 non-null float64\n",
      "INDUS       490 non-null float64\n",
      "CHAS        490 non-null float64\n",
      "NOX         490 non-null float64\n",
      "RM          490 non-null float64\n",
      "AGE         490 non-null float64\n",
      "DIS         490 non-null float64\n",
      "TAX         490 non-null float64\n",
      "PTRATIO     490 non-null float64\n",
      "B           490 non-null float64\n",
      "LSTAT       490 non-null float64\n",
      "RAD_1       490 non-null uint8\n",
      "RAD_2       490 non-null uint8\n",
      "RAD_3       490 non-null uint8\n",
      "RAD_4       490 non-null uint8\n",
      "RAD_5       490 non-null uint8\n",
      "RAD_6       490 non-null uint8\n",
      "RAD_7       490 non-null uint8\n",
      "RAD_8       490 non-null uint8\n",
      "RAD_24      490 non-null uint8\n",
      "MEDV        490 non-null float64\n",
      "log_MEDV    490 non-null float64\n",
      "dtypes: float64(14), uint8(9)\n",
      "memory usage: 61.7 KB\n"
     ]
    }
   ],
   "source": [
    "fe_data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(r'boston_housing.csv')\n",
    "\n",
    "#删除大于等于50的赝本\n",
    "df = df[df.MEDV < 50]\n",
    "#输出样本数和特征维数\n",
    "y=df['MEDV']\n",
    "X=df.drop('MEDV',axis=1)\n",
    "\n",
    "#Rad的含义是距离高速公路的便利指数，数值型的，可换成离散特征/类别型特征编码\n",
    "X[\"RAD\"].astype(\"object\")\n",
    "x_cat = X[\"RAD\"]\n",
    "x_cat = pd.get_dummies(x_cat,prefix = 'RAD')\n",
    "\n",
    "X=X.drop(\"RAD\",axis = 1)\n",
    "\n",
    "#特征名称，用于保存特征工程结果\n",
    "feat_names = X.columns\n",
    "\n",
    "#数据标准化\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "#分别初始化对特征和目标值的标准化器\n",
    "mm_X=MinMaxScaler()\n",
    "mm_y=MinMaxScaler()\n",
    "\n",
    "#fit(): Method calculates the parameters μ and σ and saves them as internal objects.'\n",
    "#transform(): Method using these calculated parameters apply the transformation to a particular dataset.\n",
    "#fit_transform()：将前两种方法合并，fit + transform，然后对数据集使用。\n",
    "X= mm_X.fit_transform(X)\n",
    "\n",
    "#对y标准化是非必须的，但是好处是不同问题的w差异不大，同时正则参数的范围也有限\n",
    "y = mm_y.fit_transform(y.values.reshape(-1,1))\n",
    "\n",
    "fe_data = pd.DataFrame(data = X,columns = feat_names,index = df.index)\n",
    "fe_data = pd.concat([fe_data,x_cat],axis=1,ignore_index = False)\n",
    "\n",
    "#加上标签\n",
    "fe_data[\"MEDV\"] = y\n",
    "fe_data[\"log_MEDV\"]= log_y\n",
    "\n",
    "#保存结果到文件\n",
    "fe_data.to_csv('FE_mm_boston_housing.csv',index =False)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
